# import matplotlib.pyplot as plt
# plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体
# plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
#
# import pandas as pd
# import numpy as np
# #import matplotlib.pyplot as plt
# from scipy.stats import pearsonr
# import seaborn as sns
#
# # ====================== 1. 数据加载与预处理 ======================
# # 老年护理机构数据（第一张表格）
# elder_care_data = {
#     "Year": [2010, 2020, 2022, 2023],
#     "Nursing_Homes": [14, 64, 93, 99],
#     "Area_sqm": [101048, 446961, 498791, 500796],
#     "Beds": [3285, 19597, 26584, 29051],
#     "Hospitalizations": [np.nan, 28571, 47359, 48872],
#     "Elder_Hospitals": [4, 3, 3, 4],
#     "Elder_Hospitalizations": [np.nan, 1573, 1914, 12792],
#     "Home_Beds": [43880, 55204, 58037, 88718]
# }
# df_care = pd.DataFrame(elder_care_data).interpolate()  # 线性插值填充缺失值
#
# # 医疗资源数据（第二张表格）
# medical_data = {
#     "District": ["浦东新区", "黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区", "杨浦区",
#                 "闵行区", "宝山区", "嘉定区", "金山区", "松江区", "青浦区", "奉贤区", "崇明区"],
#     "Institutions": [1283, 326, 403, 386, 405, 228, 177, 274, 530, 388, 445, 298, 273, 429, 336, 350],
#     "Beds": [24535, 16986, 19260, 8554, 16493, 7976, 10019, 13909, 13919, 10828, 11159, 6215, 6107, 7917, 5458, 3882],
#     "Medical_Staff": [36206, 30388, 30115, 12923, 24555, 11600, 13372, 18613, 17820, 10588, 12658, 7570, 9095, 8391, 7249, 5250],
#     "Doctors": [14099, 10715, 10466, 4510, 8508, 4154, 4834, 6172, 6223, 3734, 4705, 2750, 3309, 3227, 2774, 2107],
#     "Nurses": [15403, 14162, 14066, 5957, 11477, 5317, 6247, 9119, 8037, 4813, 5800, 3407, 3726, 3732, 2973, 2015]
# }
# df_medical = pd.DataFrame(medical_data)
#
# # 文化设施数据（第三张表格）
# culture_data = {
#     "Category": ["艺术机构", "艺术表演团体", "艺术表演场馆", "艺术展览创作机构", "公共图书馆", "少儿图书馆",
#                 "档案机构", "群艺馆/文化馆(站)", "群众艺术馆/文化馆", "文化站", "文物机构",
#                 "文物保护管理机构", "博物馆", "其他文物机构", "文化市场经营机构", "新闻出版机构", "其他文旅机构"],
#     "Institutions": [332, 261, 59, 12, 20, 2, 2482, 237, 19, 218, 112, 5, 85, 5, 2387, 4472, 54],
#     "Employees": [8670, 7057, 1229, 384, 2135, 83, 4017, 4674, 890, 3784, 5023, 103, 4748, 135, 49080, 107840, 1205]
# }
# df_culture = pd.DataFrame(culture_data)
#
# # 绿地数据（第四张表格） - 修正数据长度一致
# green_data = {
#     "Year": list(range(1990, 2024)),
#     "Green_Area": [3570, 6561, 12601, 28865, 30609, 31795, 34256, 116929, 120148, 122283,
#                   124204, 124295, 125741, 127332, 131681, 136327, 139427, 157785, 164611,
#                   171215, 172646, 173256] + [173256] * 12,  # 补充缺失年份数据（假设2022年后不变）
#     "Park_Green": [983, 1793, 4812, 12038, 13307, 13899, 14777, 15406, 16053, 16446,
#                   16848, 17142, 17789, 18395, 18957, 19805, 20578, 21425, 21981, 22463,
#                   22980, 23497] + [23497] * 12,  # 补充缺失年份数据
#     "New_Green": [186, 516, 1458, 2116, 1691, 1629, 1190, 1096, 1223, 1063, 1038, 1050,
#                  1105, 1190, 1221, 1361, 1307, 1321, 1202, 1032, 1055, 1044] + [1044] * 12
# }
# df_green = pd.DataFrame(green_data)
#
# # ====================== 2. 资源分布分析 ======================
# # 假设各行政区老年人口（万） - 实际数据需从统计局获取
# np.random.seed(42)
# df_medical["Elderly_Pop"] = np.random.randint(5, 30, size=len(df_medical))
#
# # 计算医疗资源密度指标
# df_medical["Beds_per_10k"] = df_medical["Beds"] / df_medical["Elderly_Pop"]
# df_medical["Doctors_per_10k"] = df_medical["Doctors"] / df_medical["Elderly_Pop"]
#
# # 基尼系数计算函数
# def gini_coefficient(x):
#     x = np.sort(x[x > 0])
#     n = len(x)
#     cumx = np.cumsum(x)
#     return (n + 1 - 2 * np.sum(cumx) / cumx[-1]) / n
#
# gini_beds = gini_coefficient(df_medical["Beds"])
# gini_doctors = gini_coefficient(df_medical["Doctors"])
#
# # ====================== 3. 可视化分析 ======================
# plt.figure(figsize=(15, 10))
#
# # 医疗资源分布
# plt.subplot(2, 2, 1)
# sns.barplot(x="Beds_per_10k", y="District", data=df_medical.sort_values("Beds_per_10k"))
# plt.title("每万老年人床位数分布（降序）")
# plt.xlabel("床位数/万老人")
#
# # 养老机构增长趋势
# plt.subplot(2, 2, 2)
# plt.plot(df_care["Year"], df_care["Nursing_Homes"], marker='o')
# plt.title("老年护理机构数量增长（2010-2023）")
# plt.xlabel("年份")
# plt.ylabel("机构数量")
#
# # 绿地面积变化
# plt.subplot(2, 2, 3)
# plt.plot(df_green["Year"], df_green["Park_Green"], color='green')
# plt.title("公园绿地面积变化（1990-2023）")
# plt.xlabel("年份")
# plt.ylabel("面积（公顷）")
#
# # 文化设施构成
# plt.subplot(2, 2, 4)
# df_top_culture = df_culture.nlargest(5, "Institutions")
# plt.pie(df_top_culture["Institutions"], labels=df_top_culture["Category"], autopct="%1.1f%%")
# plt.title("文化设施数量占比（Top5）")
#
# plt.tight_layout()
# plt.show()
#
# # ====================== 4. 相关性分析 ======================
# # 假设住院人次与床位数关系（实际需健康数据）
# corr, p_value = pearsonr(df_medical["Beds"], df_medical["Doctors"])
# print(f"床位数与医生数相关性: r={corr:.3f}, p={p_value:.4f}")
#
# # ====================== 5. 优化建议生成 ======================
# def generate_recommendations(df):
#     low_beds = df[df["Beds_per_10k"] < df["Beds_per_10k"].median()]
#     recs = []
#     for _, row in low_beds.iterrows():
#         rec = (
#             f"{row['District']}: 当前每万老年人床位数{row['Beds_per_10k']:.1f}张，"
#             f"低于中位数{df['Beds_per_10k'].median():.1f}。建议："
#             f"新增{int(df['Beds'].median() - row['Beds'])}张床位。"
#         )
#         recs.append(rec)
#     return recs
#
# recommendations = generate_recommendations(df_medical)
# print("\n优化建议：")
# for i, rec in enumerate(recommendations[:3]):  # 打印前3条
#     print(f"{i+1}. {rec}")
#
# # ====================== 6. 输出关键指标 ======================
# print("\n关键指标：")
# print(f"- 医疗床位基尼系数: {gini_beds:.3f}（>0.4表示严重不均）")
# print(f"- 2023年老年护理机构数量: {df_care.iloc[-1]['Nursing_Homes']}所，十年增长{df_care['Nursing_Homes'].iloc[-1]/df_care['Nursing_Homes'].iloc[0]:.1f}倍")
# print(f"- 2023年人均公园绿地: {df_green['Park_Green'].iloc[-1]/2500:.2f}㎡（按2500万人口估算）")
import geopandas as gpd
import pandas as pd
import folium
from folium.plugins import HeatMap
import matplotlib.pyplot as plt
import contextily as ctx

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# ====================== 1. 准备数据 ======================
# 上海各区医疗/康养资源数据（示例数据）
data = {
    "District": ["浦东新区", "黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区", "杨浦区",
                "闵行区", "宝山区", "嘉定区", "金山区", "松江区", "青浦区", "奉贤区", "崇明区"],
    "Nursing_Homes": [25, 8, 12, 10, 9, 11, 7, 10, 15, 12, 10, 6, 8, 7, 6, 5],
    "Elderly_Beds": [12000, 8500, 9500, 4200, 8200, 4000, 5000, 7000, 7000, 5400, 5600, 3100, 3000, 3900, 2700, 1900],
    "Medical_Institutions": [1283, 326, 403, 386, 405, 228, 177, 274, 530, 388, 445, 298, 273, 429, 336, 350],
    "Longitude": [121.47, 121.48, 121.43, 121.42, 121.46, 121.39, 121.49, 121.52,
                 121.38, 121.48, 121.26, 121.34, 121.24, 121.12, 121.47, 121.40],
    "Latitude": [31.22, 31.23, 31.19, 31.21, 31.23, 31.25, 31.27, 31.27,
                31.11, 31.40, 31.38, 30.75, 31.00, 31.15, 30.92, 31.62]
}

df = pd.DataFrame(data)

# 计算每万老年人床位数（假设老年人口数据）
df['Elderly_Pop'] = [180, 60, 70, 50, 65, 75, 55, 80, 120, 90, 85, 40, 75, 50, 45, 30]  # 单位：千人
df['Beds_per_10k'] = df['Elderly_Beds'] / (df['Elderly_Pop'] / 10)

# ====================== 2. 获取上海行政区划地理数据 ======================
# 可以从以下网址下载上海GeoJSON文件：
# https://geo.datav.aliyun.com/areas_v3/bound/310000_full.json
# 或者使用以下代码直接加载（需要联网）
url = "https://geo.datav.aliyun.com/areas_v3/bound/310000_full.json"
shanghai_districts = gpd.read_file(url)

# 确保区名匹配
name_mapping = {
    '黄浦区': '黄浦区',
    '徐汇区': '徐汇区',
    '长宁区': '长宁区',
    '静安区': '静安区',
    '普陀区': '普陀区',
    '虹口区': '虹口区',
    '杨浦区': '杨浦区',
    '闵行区': '闵行区',
    '宝山区': '宝山区',
    '嘉定区': '嘉定区',
    '浦东新区': '浦东新区',
    '金山区': '金山区',
    '松江区': '松江区',
    '青浦区': '青浦区',
    '奉贤区': '奉贤区',
    '崇明区': '崇明区'
}

shanghai_districts['name'] = shanghai_districts['name'].map(name_mapping)

# 合并数据
shanghai_data = shanghai_districts.merge(df, left_on='name', right_on='District')

# ====================== 3. 使用Folium创建交互式热力图 ======================
# 创建基础地图
m = folium.Map(location=[31.23, 121.47], zoom_start=10, tiles='CartoDB positron')

# 准备热力图数据 (使用养老院数量作为权重)
heat_data = [[row['Latitude'], row['Longitude'], row['Nursing_Homes']] for _, row in df.iterrows()]

# 添加热力图
HeatMap(heat_data,
        name='养老院分布热力图',
        min_opacity=0.5,
        max_opacity=0.8,
        radius=20).add_to(m)

# 添加区划边界
folium.GeoJson(
    shanghai_districts,
    name='行政区划',
    style_function=lambda feature: {
        'fillColor': '#ffff00',
        'color': 'blue',
        'weight': 2,
        'fillOpacity': 0.1
    },
    tooltip=folium.GeoJsonTooltip(fields=['name'], aliases=['区名'])
).add_to(m)

# 添加图层控制
folium.LayerControl().add_to(m)

# 显示地图
m.save('shanghai_elderly_care_heatmap.html')  # 保存为HTML文件
m

# ====================== 4. 使用Geopandas绘制静态热力图 ======================
fig, ax = plt.subplots(figsize=(12, 10))

# 绘制区划
shanghai_data.plot(column='Beds_per_10k',
                   cmap='YlOrRd',
                   scheme='quantiles',
                   edgecolor='black',
                   linewidth=0.5,
                   legend=True,
                   ax=ax)

# 添加标注
for idx, row in shanghai_data.iterrows():
    plt.annotate(text=row['District'],
                 xy=(row.geometry.centroid.x, row.geometry.centroid.y),
                 ha='center', fontsize=8)

# 添加底图
ctx.add_basemap(ax, crs=shanghai_data.crs.to_string(), source=ctx.providers.CartoDB.Positron)

# 设置标题和图例
ax.set_title('上海市各区每万老年人床位数分布', fontsize=16)
ax.set_axis_off()
plt.tight_layout()
plt.show()